(function(){

YAHOO.pendular.Application = function(config){
    if (!config) {
        config = {};
    }
    YAHOO.lang.augmentObject(config, {
        locale: "en_US",
        pentaho: "../../../"
    });
    this.config = config;
    YAHOO.pendular.app = this;
    this.init();
};

YAHOO.lang.extend(YAHOO.pendular.Application, Object, {
    init: function(){
        var me = this;
        this.initRepository();
        this.initRepositoryKeywordDataSource();
        this.initTagCloud();
        this.initAutocomplete();
        this.initMenuBar();
        this.initProperties();
        this.initWindowManager();
        this.initResults();
        this.repository.load({
            scope: this,
            success: this.repositoryLoaded,
            failure: this.loadRepositoryFailed
        });
     },
    repositoryLoaded: function(){
        this.repositoryTagCloud.render();
        this.initButtons();
        this.initQuery();
        this.autoComplete.keyListener.enable();
        this.autoComplete.focus();
    },
    loadRepositoryFailed: function(){
    },
    initRepository: function(){
        this.repository = new YAHOO.pendular.Repository({
            url: this.config.pentaho + "SolutionRepositoryService"
        });
    },
    initMenuBar: function(){
        var me = this, mb = this.menuBar = new YAHOO.pendular.MenuBar();
        mb.onFolderMenuItemClicked.subscribe(function(ev, args) {
            me.windowManager.openLink({
                title: ""
            });
        });
        mb.onWindowMenuItemClicked.subscribe(function(ev, args) {
            var key = args[0];
            me.windowManager.setActiveEl(key);
        });
        mb.onSearchMenuItemClicked.subscribe(function(ev, args){
            me.windowManager.setActiveEl("pendular-main");
        });
        mb.onCloseMenuItemClicked.subscribe(function(ev, args){
            var wm = me.windowManager, el = wm.activeEl;
            if (el === "pendular-main") {
                return;
            }
            wm.close(el);
        });
    },
    initQuery: function(href){
        if (YAHOO.lang.isUndefined(href)){
            href = document.location.href;
        }
        var ioqm = href.indexOf("?");
        if (ioqm===-1){
            return;
        }
        var q = href.substr(ioqm + 1);
        if (q.length===0){
            return;
        }
        var params = q.split("&"),
            numParams = params.length,
            param, name, value, i;
        for (i=0; i<numParams; i++){
            param = params[i].split("=");
            name = param[0];
            value = param[1];
            switch (name) {
                case "query":
                    this.doFind(value);
            }
        }
    },
    initTagCloud: function(){
        var me = this,
            tg = me.repositoryTagCloud = new YAHOO.pendular.RepositoryTagCloud({
                repository: me.repository
            });
        tg.onWordClicked.subscribe(function(ev, args){
            me.addWord(args[0]);
        });
        me.repositoryKeywordDataSource.onKeywordsFound.subscribe(
            function(ev, args){
                tg.applyStyle(args[1]);
            }
        );
    },
    initProperties: function(){
        this.config.propertiesLoader = new YAHOO.pendular.PropertiesLoader();
        var labelProvider = new YAHOO.pendular.LabelProvider(this.config).load();
/*            
        var me = this,
            config = this.config;
        this.propertiesLoader = new YAHOO.pendular.PropertiesLoader();
        this.propertiesLoader.load({
            basename: "locale/messages",
            locale: config.locale,
            callback: {
                scope: me,
                success: function(loader, o, settings) {
                    this.initLabels(settings);
                },
                failure: function() {
                }
            }
        });
    },
    initLabels: function(settings){
        var key, value, el;
        for (key in settings){
            if (!YAHOO.lang.hasOwnProperty(settings, key)){
                continue;
            }
            el = YAHOO.util.Dom.get("pendular-" + key + "-label");
            if (!el){
                continue;
            }
            el.innerHTML = settings[key];
        }
*/
    },
    initRepositoryKeywordDataSource: function(){
        this.repositoryKeywordDataSource = new YAHOO.pendular.RepositoryKeywordDataSource({
            repository: this.repository
        });
    },
    initAutocomplete: function(){
        var me = this;
        this.autoComplete = new YAHOO.pendular.AutoComplete();
    },
    initResults: function(){
        var me = this;
        var ds = me.resultDataSource = new YAHOO.pendular.RepositoryResultDataSource({
            repository: this.repository
        });
        var dt = me.repositoryDataTable = new YAHOO.pendular.RepositoryDataTable({
            datasource: ds,
            maxDescLength: 50
        });
        dt.onResultLinkClicked.subscribe(function(ev, args){
            var link = args[0];
            me.windowManager.openLink(link);
        });
    },
    initButtons: function(){
        var top1,top2;
        if (YAHOO.env.ua.webkit) {
            top1 = 0;
            top2 = 0;
        }
        else
        if (YAHOO.env.ua.gecko) {
            top1 = 1;
            top2 = 1;
        }
        else
        if (YAHOO.env.ua.opera) {
            top1 = 1;
            top2 = 1;
        }
        var cb = this.clearButton = YAHOO.util.Dom.get("pendular-clear");
        cb.style.top = top1 + "px";
        cb.onclick = function(){
            YAHOO.pendular.app.clear();
        };
        var fb = this.findButton = YAHOO.util.Dom.get("pendular-find");
        fb.style.top = top2 + "px";
        fb.onclick = function(){
            YAHOO.pendular.app.find();
        };
    },
    initWindowManager: function(){
        var me = this,
            wm = me.windowManager = new YAHOO.pendular.WindowManager();
        wm.onOpenWindow.subscribe(function(ev, args){
            var link = args[3];
            me.menuBar.addWindowMenuItemForLink(link);
        });
        wm.onCloseWindow.subscribe(function(ev, args){
            var key = args[0];
            me.menuBar.removeWindowMenuItem("pendular-menuitem-"+key);
        });
        wm.onActivate.subscribe(function(ev, args){
            var o = args[0], n = args[1];
            me.menuBar.checkWindowMenuItem("pendular-menuitem-"+n);
        });
    },
    addWord: function(link){
        var word = link.innerHTML,
            keyword = link.getAttribute("data-keyword"),
            el = this.autoComplete.getInputEl(),
            value = el.value,
            keywords = this.repository.keywords.makeKeywords(value),
            keywordIndex = this.repository.keywords.getKeywordIndex(keywords)
        ;
        if (keywordIndex[keyword]) {
            value = value.replace(new RegExp(word,"ig"), "");
        }
        else {
            value = (value.length? value + " " : "") + word + " ";
        }
        value = value.replace(/\s+/g, " ");
        this.repositoryKeywordDataSource.sendRequest(value);
        el.value = value;
        el.focus();
        this.doFind(value);
    },
    doFind: function(query){
        if (YAHOO.lang.isObject(query) && !YAHOO.lang.isUndefined(query.href)) {
            this.initQuery(query.href);
        }
        else {
            this.autoComplete.getInputEl().value = decodeURIComponent(query);
            this.find();
        }
    },
    find: function(){
        var me = this,
            q = me.autoComplete.getInputEl().value,
            dt = me.repositoryDataTable;
        me.resultDataSource.sendRequest(
            q,
            {
                scope: dt,
                success: function(a,b,c) {
                    dt.renderResult(b);
                },
                failure: function(a,b,c) {
                }
            }
        );
    },
    clear: function(){
        var me = this;
        me.repositoryTagCloud.applyDefaultStyles();
        me.autoComplete.clear();
    }
});

})();
